/*
 * Copyright (C) 2015 UFreedom
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.ufreedom.floatingview.transition;

import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringConfig;
import com.facebook.rebound.SpringSystem;
import com.facebook.rebound.SpringUtil;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;

import java.lang.ref.WeakReference;

/**
 * YumFloating
 *
 * @author UFreedom
 * @since 2021-03-31
 */
public class YumFloating implements ITransition, Rebound {

    private SpringSystem mSpringSystem;
    private WeakReference<Component> mTargetViewWeakReference;

    /**
     * YumFloating
     *
     * @param targetView
     * @param springSystem
     */
    public YumFloating(Component targetView, SpringSystem springSystem) {
        mTargetViewWeakReference = new WeakReference<Component>(targetView);
        this.mSpringSystem = springSystem;
    }

    /**
     * YumFloating
     *
     * @param targetView
     */
    public YumFloating(Component targetView) {
        mTargetViewWeakReference = new WeakReference<Component>(targetView);
    }

    /**
     * getTargetView
     *
     * @return Component
     */
    public Component getTargetView() {
        return mTargetViewWeakReference.get();
    }

    /**
     * alpha
     *
     * @param alpha
     */
    @Override
    public void setAlpha(float alpha) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setAlpha(alpha);
        }
    }

    /**
     * rotation
     *
     * @param rotation
     */
    @Override
    public void setRotation(float rotation) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setRotation(rotation);
        }
    }

    /**
     * rotationX
     *
     * @param rotationX
     */
    @Override
    public void setRotationX(float rotationX) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setRotation(rotationX);
        }
    }

    /**
     * rotationY
     *
     * @param rotationY
     */
    @Override
    public void setRotationY(float rotationY) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setRotation(rotationY);
        }
    }

    /**
     * scaleX
     *
     * @param scaleX
     */
    @Override
    public void setScaleX(float scaleX) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setScaleX(scaleX);
        }
    }

    /**
     * scaleY
     *
     * @param scaleY
     */
    @Override
    public void setScaleY(float scaleY) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setScaleY(scaleY);
        }
    }

    /**
     * scrollX
     *
     * @param scrollX
     */
    @Override
    public void setScrollX(int scrollX) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setScaleX(scrollX);
        }
    }

    /**
     * scrollY
     *
     * @param scrollY
     */
    @Override
    public void setScrollY(int scrollY) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setScaleY(scrollY);
        }

    }

    /**
     * translationX
     *
     * @param translationX
     */
    @Override
    public void setTranslationX(float translationX) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setTranslationX(translationX);
        }
    }

    /**
     * translationY
     *
     * @param translationY
     */
    @Override
    public void setTranslationY(float translationY) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setTranslationY(translationY);
        }
    }

    /**
     * x
     *
     * @param x
     */
    @Override
    public void setX(float x) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setTranslationX(x);
        }
    }

    /**
     * y
     *
     * @param y
     */
    @Override
    public void setY(float y) {
        Component targetView;
        if ((targetView = getTargetView()) != null) {
            targetView.setTranslationY(y);
        }
    }

    /**
     * createSpringByBouncinessAndSpeed
     *
     * @param bounciness
     * @param speed
     * @return Spring
     */
    @Override
    public Spring createSpringByBouncinessAndSpeed(double bounciness, double speed) {
        return mSpringSystem.createSpring()
                .setSpringConfig(SpringConfig.fromBouncinessAndSpeed(bounciness, speed));
    }

    /**
     * createSpringByTensionAndFriction
     *
     * @param tension
     * @param friction
     * @return Spring
     */
    @Override
    public Spring createSpringByTensionAndFriction(double tension, double friction) {
        return mSpringSystem.createSpring()
                .setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(tension, friction));
    }

    /**
     * transition
     *
     * @param progress
     * @param startValue
     * @param endValue
     * @return float
     */
    @Override
    public float transition(double progress, float startValue, float endValue) {
        return (float) SpringUtil.mapValueFromRangeToRange(progress, 0, 1, startValue, endValue);
    }

    /**
     * clear
     */
    public void clear() {
        Component view = getTargetView();
        if (view != null) {
            ComponentContainer viewParent = (ComponentContainer) view.getComponentParent();
            if (viewParent instanceof ComponentContainer) {
                ComponentContainer parent = viewParent;
                parent.removeComponent(view);
                mTargetViewWeakReference.clear();
            }
        }
    }

}
